# -*- coding:utf-8 -*-
"""
@Author : 审心
@Time : 2023/5/12 10:51
"""
import time
from dataclasses import dataclass
from typing import List, Optional

from DrissionPage import WebPage
from DrissionPage.action_chains import ActionChains
from DrissionPage.chromium_element import ChromiumElement
from DrissionPage.chromium_tab import ChromiumTab
from DrissionPage.commons.keys import Keys
from DrissionPage.errors import ElementNotFoundError

from autoTask.taobao.ztc.common import WebOperation
from autoTask.taobao.ztc.gjc.OptiBid.Enum import TbType
from autoTask.taobao.ztc.gjc.OptiBid.pojo import FilterRule
from common.utils import web_page_util
from common.utils.web_page_util import Tap, Input, ActionChain
from common.logger.log import log_


@dataclass
class AM:
    """
    阿明工具操作对象
    """

    @staticmethod
    def open_view(p: WebPage):
        """
        打开阿明工具页面 (直通车首页执行)
        :param p: 网页对象
        :return:
        """
        ming_ele = None
        # 阿明工具元素
        for i in range(3):
            ming_ele = p("#aming-tool-summary-super-optimize")
            if ming_ele:
                Tap(ming_ele, "打开阿明工具首页失败", by_js=True)()
                AM.loading_tb(p)
                break
            p.refresh()
        if not ming_ele:
            raise ElementNotFoundError("打开阿明工具首页失败")
        log_.info("打开阿明工具页面成功")


    @staticmethod
    def goto_gjc_tag(p: WebPage):
        """
        前往标准推广关键词标签页 (起始是 am_open_view 执行后界面)
        :param p: 网页对象
        :return:
        """
        e = p("@@class=tab-label-contain@@text():关键词优化", timeout=0)
        if e:
            Tap(e, "跳转到关键词优化标签页", by_js=True)()
        else:
            if p("@@class=yqs-panel@@text():标准推广计划", timeout=3):
                AM.tb_select_all(p)
                Tap(p(".search-tool")("t:span@@text():批量优化计划"), "点击批量优化计划")()
                AM.loading_tb(p)
            if p("@@class=yqs-panel@@text():多计划批量优化"):
                AM.tb_select_all(p)
                Tap(p(".search-tool")("t:span@@text():批量优化单元"), "点击批量优化推广单元")()
                AM.loading_tb(p)
        if not p("@@class=yqs-panel@@text():关键词优化"):
            raise RuntimeError("前往关键词优化标签页失败")
        log_.info("前往关键词优化标签页成功")


    @staticmethod
    def goto_rq_tag(p: WebPage):
        """
        前往人群优化标签页 (起始是 am_open_view 或 goto_gjc_tag 执行后界面)
        :param p: 网页对象
        :return:
        """
        e = p("@@class=tab-label-contain@@text():人群优化", timeout=0)
        if e:
            Tap(e, "跳转到人群优化标签页", by_js=True)()
            AM.loading_tb(p)
        else:
            if p("@@class=yqs-panel@@text():标准推广计划", timeout=3):
                AM.tb_select_all(p)
                Tap(p(".search-tool")("t:span@@text():批量优化计划"), "点击批量优化计划")()
                AM.loading_tb(p)
            if p("@@class=yqs-panel@@text():多计划批量优化"):
                AM.tb_select_all(p)
                Tap(p(".search-tool")("t:span@@text():批量优化单元"), "点击批量优化推广单元")()
                AM.loading_tb(p)
        if not p("@@class=yqs-panel@@text():人群优化"):
            raise RuntimeError("前往人群优化优化标签页失败")
        log_.info("前往人群优化标签页成功")


    @staticmethod
    def set_tb_data_cycle(p: WebPage, cycle: str, tb_ele: ChromiumElement):
        """
        设置表格的数据周期
        :param p: 网页对象
        :param cycle: 数据周期
        :param tb_ele: 表格元素
        :return:
        """
        Tap(tb_ele(".search-tool")(".mainTime el-popover__reference")("tag:input"),
            msg="打开设置数据周期弹窗失败", by_js=True)()
        Tap(p("@@class:el-popover el-popper yqs-date-time-pop@@aria-hidden=false")(f"tx:{cycle}"),
            msg=f"设置数据周期为 [{cycle}] 失败", by_js=True)()
        AM.loading_tb(p)


    @staticmethod
    def set_filter_template(p: WebPage, cycle: str, tb_type: int):
        """
        设置筛选模板
        :param p: 网页对象
        :param cycle: 数据周期
        :param tb_type: 表格类型 1 关键词 2 人群
        :return:
        """
        tb = AM.get_tb_ele(p, tb_type)
        AM.set_tb_data_cycle(p, cycle, tb)
        Tap(tb("模板高级筛选"), "打开模板高级筛选失败", by_js=True, after_delay=5, before_delay=5)()
        Tap(AM.get_open_template(p)("t:span@@text()=查找"), "点击查找设置模板失败", after_delay=(2, 3))()
        AM.loading_tb(p)
        log_.info(f"设置过滤模板以及日期成功 日期 : {cycle} 表格类型: {tb_type}")


    @staticmethod
    def set_gjc_bid(p: WebPage, bid: [str, float], is_test_execute: bool):
        """
        设置关键词出价
        :param p: 网页对象
        :param bid: 出价
        :param is_test_execute: 是否测试执行
        :return:
        """
        dialog = p("c:yqs-template-update-price-package-words-dialog")
        if dialog and dialog.states.is_displayed:
            e = dialog("tx:自主出价")
            Tap(e.parent(), "点击自主出价", by_js=True, after_delay=1)()
            Input(e("t:input"), "输入出价", vals=bid, after_delay=1)()
            if is_test_execute:
                Tap(dialog("t:button@@text():取"), "取消修改出价", is_random=False)()
            else:
                Tap(dialog("t:button@@text():确"), "确定修改出价", is_random=False)()
        else:
            dialog = p('c:yqs-template-set-keywrod-price-dialog')
            if dialog and dialog.states.is_displayed:
                e = dialog("@@class=price-label@@text():自定义出价")
                Tap(e.prev(), "选择自定义出价", by_js=True, after_delay=1)()
                Input(e.next()("t:input"), msg="输入自定义出价", vals=bid, after_delay=1)()
                if is_test_execute:
                    ActionChains(p).key_down(Keys.ESCAPE)
                else:
                    Tap(dialog("tx:确认修改"), "确定修改出价")()
            else:
                log_.warn("设置关键词出价失败")
                return
        log_.info(f"设置关键词出价成功 设定价格 : {bid} 是否为测试: {is_test_execute}")


    @staticmethod
    def set_rq_bid(p: WebPage, bid: [str, int], is_test_execute: bool):
        dialog = p("c:yqs-template-person-price-update-dialog")
        if dialog and dialog.states.is_displayed:
            Input(dialog("t:input"), "输入溢价", vals=bid, after_delay=1)()
            if is_test_execute:
                Tap(dialog("t:button@@text():取"), "取消修改出价", is_random=False)()
            else:
                Tap(dialog("t:button@@text():确"), "确定修改出价", is_random=False)()
        else:
            log_.warn("设置人群溢价失败")


    @staticmethod
    def init_filter_template(p: WebPage, tb_type: int, filter_rule_list: List[FilterRule]):
        """
        初始化高级筛选模板内容
        :param p: 网页对象
        :param tb_type: 表格状态
        :param filter_rule_list: 过滤条件列表
        :return:
        """
        # 若为人群时重定义字段名称
        if tb_type == TbType.RQ.value:
            for item in filter_rule_list:
                if item.field == '总收藏加购成本':
                    item.field = '总加购成本'
        if len(filter_rule_list) > 0:
            tb = AM.get_tb_ele(p, tb_type)
            Tap(tb("模板高级筛选"), "打开模板高级筛选失败", is_random=False, after_delay=5, before_delay=5)()
            # 获取当前打开的模板设置
            mod = AM.get_open_template(p)
            Tap(mod("重置"), "重置模板设置失败", is_random=False)()
            for _ in range(0, len(filter_rule_list) - 1):
                Tap(mod(".operate-header")(".el-icon-plus"), "添加模板高级筛选条件时失败", by_js=True)()
            # 设置筛选 条件 条目值
            es = mod.eles(".operate-group-item")
            if len(es) != len(filter_rule_list):
                raise RuntimeError(
                    f"初始化模板失败, 条件条目与预期不符. 预期 : {len(filter_rule_list)} 结果: {len(es)}")
            for i, e in enumerate(es):
                log_.info(f"条件选择参数 : {filter_rule_list[i]}")
                ies = e.eles("t:input")
                Tap(ies[0], "打开下拉框失败", after_delay=3, by_js=True)()
                Tap(p("@@class=el-select-dropdown el-popper@@x-placement:start")(
                    f"tx:{filter_rule_list[i].field}")
                    , is_random=False)()
                Tap(ies[1], "打开下拉框失败")()
                Tap(p("@@class=el-select-dropdown el-popper@@x-placement:start")(filter_rule_list[i].comparator)
                    , is_random=False)()
                ies = e.eles("t:input")
                Input(ies[2], vals=filter_rule_list[i].value, msg="输入条件值失败")()
            Tap(mod("t:span@@text()=查找"), "点击查找设置模板失败", by_js=True)()
            AM.loading_tb(p)
            log_.info(f"初始化高级筛选模板成功 表格类型 : {tb_type} 模板列表 : {filter_rule_list}")


    @staticmethod
    def tb_select_all(p: WebPage):
        """
        阿明工具表格选择所有项
        :param p: 网页对象
        :return:
        """
        # 获取全选单元格
        e = next((ele for ele in p.eles(".is-group") if ele.states.is_displayed), None)
        if not e:
            raise RuntimeError("没有获取到头部操作栏 div")
        e = e("@class:el-table-column--selection")
        # 判断是否已经选中
        if not e("@class:el-checkbox is-checked", timeout=0):
            Tap(e("@class:el-checkbox"), "表格全选")()


    @staticmethod
    def loading_tb(p: WebPage, before_delay: int = 5, timeout: int = 10):
        """
        等待表格刷新完毕(加载数据元素消失)
        :param p:网页对象
        :param before_delay: 监听元素消失之前的待机时间
        :param timeout : 等待加载超时时间
        :return:
        """
        time.sleep(before_delay)
        web_page_util.wait_ele_disappear(p, ".el-loading-text", timeout)


    @staticmethod
    def get_tb_ele(p: WebPage, type_: int):
        """
        :param p: 网页对象
        :param type_: 表格类型 1 :关键词 2 : 人群
        :return:
        """
        if type_ == TbType.GJC.value:
            return p("#pane-StandardKeywords")
        elif type_ == TbType.RQ.value:
            return p("#pane-StandardPersons")
        else:
            raise RuntimeError(f"暂不支持的表格类型 : {type_}")


    @staticmethod
    def get_tb_data_count(p: WebPage, type_: int):
        """
        获取表格数据条目
        :param p:
        :param type_: 表格类型 1关键词 2人群
        :return:
        """
        count = AM.get_tb_ele(p, type_)(".c-a-t-t-tip")
        if count:
            return int(count.text)
        else:
            log_.warning(f"当前表格没有数据 类型: {type_}")
            return 0


    @staticmethod
    def get_open_template(p: WebPage) -> Optional[ChromiumTab]:
        """
        获取已经打开的模板 div 元素
        :param p: 网页对象
        :return:
        """
        return next((e for e in p.eles(".el-dialog yqs-template-senior-dialog yqs-template-common-dialog")
                     if e.states.is_displayed), None)
